unsw_tele4642_g9fandomcom-20200214-history
Dynamic Firewall (based on quota)
=Dynamic Firewall (based on Quota) on SDN= Welcome to the Group 9 Project A group of 4 from UNSW TELE4642 is runing this wiki. Group member: Kong,Youwei; Tang,Zhongtian; Wang,Xinning; Xu,Yuanfang. Background This mini project aims to provide a way to manage bandwidth usage in a software defined network. The project is based on a hotel situation. POX is used to interface with a network switch and provide the logic for the network.The scenario is that the user should buy quota to connect the Internet, and if there is no quota left, the connection between Internet will be blocked. The amount of quota is stored in a csv file. Once user buys data, pox will read the data again from csv file. This is a sample topology of an SDN controlled switch, which is a simple linear topo and emulated in Mininet below. The internet is represented by host5 in this network, and packets entering the switch that originated from this host is inspected by the switch for its destination host (using its destination MAC address), and that host's quota will be subtracted by the size of the packet in bytes. This emulates real life requests for data from the Internet, with the switch and the hosts being computers. In this case, POX is being managed by the service provider, and you give your quota division to your service provider for them to implement onto their controller. Code & Explaination This part covers the code in our project and will clearly explain the principle behind it. Basiclly, our project has 5 functions which are read (), sendout(), quota_manager() and launch(). FIrstly, initialize some global viables and read the csv data file. log = core.getLogger() policyFile = "%s/pox/pox/misc/quotablock-policies.csv" % os.environ[ 'HOME' ] host={} # To store hosts mac addresses quota={} # To store hosts quotas k = 0 # To store the number of hosts with open(policyFile, 'rb') as f: # Initialize hosts addresses and quotas reader = csv.DictReader(f) for row in reader: if row'id' 'proxy': proxy = row'mac' elif row'id' 'admin': admin = row'mac' else: k = k + 1 hostk=row'mac' b=row'quota' quotak=int(b) for i in irange(1, k): print "Host", i, "'s quota is", quotai, "bytes" print "" for i in irange(1, k): print "Host", i, "is at", hosti print "" Quota count & Block Using PacketIn Event So, before sending the packet from controller to host, controller will detect the quota first. Therefore, we set a priority level for detecting quota as 1. Every time the controller detect quota first then to judge where to send the data to host. Once the controller has detected a coming packet, the program will go into the quota_manager function which shows below. def quota_manager (event): # packet_handler handling computation of downlink data usage from Internet global quota global host global k global policyFile packet = event.parsed size = len(event.data) # size of packet in bytes pktSrc = packet.src # in_packet source MAC address pktDst = packet.dst # in_packet destination MAC address if pktSrc EthAddr(proxy): if pktDst EthAddr(admin): return for i in irange(1, k): if pktDst EthAddr(hosti): # if packet is coming from the internet if quotai > 0: # subtract their quota quotai = quotai - size with open(policyFile, 'w') as f: wr=csv.DictWriter(f,fieldnames='id','mac','quota') wr.writeheader() wr.writerow({'id':'admin','mac':admin,'quota':0}) for a in irange(1,k): h='host%s'%a wr.writerow({'id':h,'mac':hosta,'quota':quotaa}) wr.writerow({'id':'proxy','mac':proxy,'quota':0}) print "Host",i,"'s quota is",quotai,"bytes" print " " sendout (event) else: print "Host",i,"is now out of quota" print "packet being blocked" # block outgoing packet if quota print " " # is less than or equal to zero return EventHalt elif pktDst EthAddr(proxy): if pktSrc EthAddr(admin): return for i in irange(1, k): if (pktSrc EthAddr(hosti)) and (quotai <= 0) : # check the source host's quota print "Host",i,"is out of quota" print " " sendout (event) return EventHalt The method for blocking is a downlink block, there will be data send to proxy, but proxy will not send to host. It calculates the size of data first. Afterwards, for each host in the network, if there is a packet coming, it will reduce the size of packet from quota. If quota is bigger than 0, it will keep transmitting the packet which means the packet will go to the sendout function. Otherwise, it will stop the event and return EventHalt. Using FlowStatsReceived Event Anther method to count quota is using "FlowStatsReceived" event to get the individual flow statistics from switch. We use _time_func() to send the individual flow statistics request to the switch and execute the function every 5 seconds. Function handle_flow_stats() is used to handle the event, counting quota and making the block. def _timer_func (): for connection in core.openflow._connections.values(): connection.send(of.ofp_stats_request(body=of.ofp_flow_stats_request())) break log.debug("Sent %i flow/port stats request(s)", len(core.openflow._connections)) def handle_flow_stats (event): global quota global host global i global lastrecord global policyFile for q in event.stats: if q.match.dl_src EthAddr(proxy): for j in range(1,i): if (q.match.dl_dst EthAddr(hostj)): if ((q.duration_sec<5) and (quotaj>0)): quotaj=quotaj-lastrecordj with open(policyFile, 'w') as f: wr=csv.DictWriter(f,fieldnames='id','mac','quota') wr.writeheader() wr.writerow({'id':'admin','mac':admin,'quota':0}) for k in range(1,i): h='host%s'%k wr.writerow({'id':h,'mac':hostk,'quota':quotak}) wr.writerow({'id':'proxy','mac':proxy,'quota':0}) print "Host",j,"is remaining",quotaj,"bytes quota.(wrote in csv)" if quotaj<=0: print "Host",j,"is out of quota." msg=of.ofp_flow_mod() msg.priority=50 msg.hard_timeout=60 msg.match.dl_src=EthAddr(proxy) msg.match.dl_dst=EthAddr(hostj) for con in core.openflow.connections: con.send(msg) msg.match.dl_src=EthAddr(hostj) msg.match.dl_dst=EthAddr(proxy) for con in core.openflow.connections: con.send(msg) print "It is being blocked from/to the proxy now." lastrecordj=q.byte_count print "From Proxy to Host",j print q.byte_count,"bytes" print q.packet_count,"packets" print q.duration_sec,"duration" print "----------" For New user add-in & Quota top-up Once the quota of a host is minus-counted, it will be updated in data file instantly, so the data file will not miss any count. Here we define a function read() to read the data file to update the global quota{} , host{}(mac) and k (the total number of user hosts) in the controller. In the launch() function, we use timer to execute read() function every 30 seconds. Administrators can edit data file manully or use other processes to add new users' mac addresses and change quota in the data file which is read by controller periodically, so that the controller can count quotas for new users or reconnect users whose quotas have been topped up or refreshed without restart. def read (): # Updating hosts quotas every X seconds global policyFile global quota global host global k i = 0 with open(policyFile, 'rb') as fl: reader = csv.DictReader(fl) for row in reader: if row'id' 'proxy': proxy = row'mac' elif row'id' 'admin': admin = row'mac' else: i = i + 1 quotai = int(row'quota') hosti = row'mac' k = i print "All hosts quota have been updated" for i in irange(1, k): print "Host", i, "'s quota is", quotai, "bytes" print "" Other Functions The function sendout() is for packet sending which is as same as what we have done in lab2. def sendout (event): # flood packet msg = of.ofp_packet_out() msg.in_port = event.port msg.data = event.ofp msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD)) event.connection.send(msg) In the launch() function, the controller add listener for 'PacketIn' event for quota_manager() function and read the data file periodically. def launch (): core.openflow.addListenerByName("PacketIn", quota_manager, priority = 1) #Monitor PacketIn Event Timer(30, read, recurring = True) #Timer for activating read function Code Test Testing Files quota.py -- controller (based on PacketIn event) quotablock.py -- controller (based on FlowStatsReceived event) quotablock-policies.csv -- data file Division of work First we discussed this project together and come up with some ideas. We had two plans in the beginning and decided one later. Wang Xinning and Tang Zhongtian mainly write the code, and run the test. Kong Youwei and Xu Yuanfang help doing research online, such as finding code examples. Background is written by Xu Yuanfang. Code part of this wiki is written and explained by Youwei Kong, inder to show how the quota and block function works. Latest activity Photos and videos are a great way to add visuals to your wiki. Find videos about your topic by exploring Wikia's Video Library. Category:Browse